// Implementation of HTTP getter, using CURL.
// Copyright 2006 (C) Ralph Thomas

#include <util/http.h>
#include <curl/curl.h>
#include <stdexcept>
//
// We perform concatenation operations most of the time, so avoid
// the (huge) realloc overhead by using rope (an SGI extension).
//
#include <ext/rope>

namespace sgi = __gnu_cxx;

namespace util {
	static size_t curl_write( void* ptr, size_t size, size_t no, void* d ) {
		if( !d ) return 0;
		if( !ptr ) return 0;
		sgi::crope* buffer( reinterpret_cast<sgi::crope*>( d ) );
		buffer->append( reinterpret_cast<char*>( ptr ), size * no );
		return size * no;
	}
	std::string http_get( const std::string& url ) {
		sgi::crope	buffer;
		CURL*		my_curl( curl_easy_init() );
		//
		// Setup CURL to get data.
		//
		curl_easy_setopt( my_curl, CURLOPT_NOPROGRESS, 1 );
		curl_easy_setopt( my_curl, CURLOPT_URL, url.c_str() );
		curl_easy_setopt( my_curl, CURLOPT_WRITEFUNCTION, &curl_write );
		curl_easy_setopt( my_curl, CURLOPT_WRITEDATA, reinterpret_cast<void*>( &buffer ) );
		curl_easy_setopt( my_curl, CURLOPT_USERAGENT, "MissionCode.org Software" );
		if( !curl_easy_perform( my_curl ) ) {
			curl_easy_cleanup( my_curl );
			//
			// It worked; transform the rope into a string and
			// return it.
			//
			return std::string( buffer.c_str(), buffer.size() );
		}
		curl_easy_cleanup( my_curl );
		throw std::runtime_error( "Couldn't fetch: " + url );
	}
}
